﻿#ifndef BUSINESSNETWORK_H
#define BUSINESSNETWORK_H

#include <memory>
#include <AppConfig/appconfig.h>
#include <protocol/protocolOption.h>
#include <hv/Channel.h>
#include <mutex>

const int NET_BUFFER_SIZE = 8196 * 2;
class Buffer {
public:
    std::string buffer;
    int64_t totalSize;
    int64_t addedSize;
    Buffer() : buffer(NET_BUFFER_SIZE, '\0'), totalSize(0), addedSize(0) {
    }
};

class BusinessNetWork
{
public:
    // 删除拷贝构造函数和拷贝赋值操作符
    BusinessNetWork(BusinessNetWork const&) = delete;
    BusinessNetWork& operator=(BusinessNetWork const&) = delete;
    // 提供一个全局唯一的接口
    static BusinessNetWork& getInstance() {
        static BusinessNetWork instance;
        return instance;
    }

    // init the tcpclient and transmission protocol setting
    void initNet();

    // get the protocol setting
    std::shared_ptr<ProtocolOption> getProtocolOption();

    // send message to the server
    void sendMessageToClient(const hv::SocketChannelPtr& channel, int type, int subtype, int64_t id1, int64_t id2, int64_t id3, unsigned char* data, int length, bool initClient = false);

    // get users SocketChannelPtr
    hv::SocketChannelPtr getChannel(uint64_t userID);
    // get user id
    uint64_t getUserID(const hv::SocketChannelPtr& channel);

    // add userSocketChannelPtr
    void addSocketChannel(uint64_t userID, const hv::SocketChannelPtr& channel);
    // erase userSocketChannelPtr
    void eraseSocketChannel(uint64_t userID);

    // check online
    bool checkTargetUserOnline(uint64_t userID);

    // new net connection
    void newNetConnection(const hv::SocketChannelPtr& channel);
    // deleteConnection
    void deleteNetConnection(const hv::SocketChannelPtr& channel);
    // get channelBuffer
    std::shared_ptr<Buffer> getChannelBuffer(const hv::SocketChannelPtr& channel);
    // get channel lock
    std::shared_ptr<std::mutex> getChannelLock(const hv::SocketChannelPtr& channel);

private:
    BusinessNetWork();
    // protocolOption
    std::shared_ptr<ProtocolOption> protoOpt;
    // use id to get channel to redirect message
    std::map<uint64_t, hv::SocketChannelPtr> userID2Channel;
    // use channel to get user id to encrypt message
    std::map<hv::SocketChannelPtr, uint64_t> channel2UserID;
    // buffer, total size, added size
    std::map<hv::SocketChannelPtr, std::shared_ptr<Buffer>> channelBuffer;
    // channel lock
    std::map<hv::SocketChannelPtr, std::shared_ptr<std::mutex>> channelLock;

};

#endif // BUSINESSNETWORK_H
